﻿using FPSO.Models;
using FPSO.HMI.Pipe;
using FPSO.Models.Constant;
using FPSO.Services;
using FPSO.Services.Impl;
using SafeLoad.NControl;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using FPSO.ViewModel.Controls;
using System.ComponentModel;
using FPSO.Models.Domain;
using PrismMVVMLibrary.DesignTime;
using Opc.Ua;
using System.Xml;
using OpcUaHelper;
using FPSO.HMI.Views;
using FPSO.Models.ViewModel.Controls;
using System.Reflection;
using FPSO.HMI.Utils;
using FPSO.HMI.Views.Dialog;

namespace FPSO.HMI.Controls
{
    /// <summary>
    /// UCOilBallast.xaml 的交互逻辑
    /// </summary>
    public partial class UCOil : UserControl
    {
        private PipeGraph ballastGraph = null;
        private PipeGraph oilGraph = null;
        private DispatcherTimer taskTimer = null;
        private UCOilBallastViewModel viewModel = null;
        private IOilBallastService oilBallastService;

        public UCOil()
        {
            InitializeComponent();

            viewModel = new UCOilBallastViewModel();
            DataContext = viewModel;
            oilBallastService = null;

            taskTimer = new DispatcherTimer();
            taskTimer.Interval = TimeSpan.FromSeconds(1);
            taskTimer.Tick += TaskTimer_Tick;
            taskTimer.Start();
        }

		protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            if (ballastGraph == null)
            {
                ballastGraph = new PipeGraph(canvasBallast);
            }
            if (oilGraph == null)
            {
                oilGraph = new PipeGraph(canvasOil);
            }
        }

        public Dictionary<string, double> GetTankVolumeDic()
        {
            Dictionary<string, double> volumeDic = new Dictionary<string, double>();
            PropertyInfo[] propertys = typeof(UCOilBallastViewModel).GetProperties();
            foreach (PropertyInfo p in propertys)
            {
                object propVal = p.GetValue(viewModel);
                if (propVal is TankViewModel t)
                {
                    volumeDic.Add(t.TankId, t.Volume);
                }
                else if (propVal is TankOilViewModel o)
                {
                    volumeDic.Add(o.TankId, o.Volume);
                }
            }
            return volumeDic;
        }
		public Dictionary<string, double> GetTankInnDic()
		{
			Dictionary<string, double> volumeDic = new Dictionary<string, double>();
			PropertyInfo[] propertys = typeof(UCOilBallastViewModel).GetProperties();
			foreach (PropertyInfo p in propertys)
			{
				object propVal = p.GetValue(viewModel);
				if (propVal is TankViewModel t)
				{
					volumeDic.Add(t.TankId, t.Level);
				}
				else if (propVal is TankOilViewModel o)
				{
					volumeDic.Add(o.TankId, o.Level);
				}
			}
			return volumeDic;
		}

		private void TaskTimer_Tick(object sender, EventArgs e)
        {
            if (ballastGraph != null)
            {
                ballastGraph.CalcPumpLines();
            }
            if (oilGraph != null)
            {
                oilGraph.CalcPumpLines();
            }
        }

        [Category("Action")]
        [Description("添加任务")]
        public event Action<string> OnAddTankTask;
		public event Action<string> OnAddBwtTankTask;

		private List<NTankMin> TankList;
        private void SelectTank_Click(object sender, MouseButtonEventArgs e)
        {
            NTankMin selTank = sender as NTankMin;
            foreach (NTankMin tank in TankList)
            {
                if (tank == selTank)
                {
                    tank.IsSelected = !tank.IsSelected;
                }
                else
                {
                    tank.IsSelected = false;
                }
            }
        }

        public string GetSelectedTank()
        {
            foreach (NTankMin tank in TankList)
            {
                if (tank.IsSelected)
                {
                    return TankConstant.GetTankId(tank.TankTitle);
                }
            }
            return "";
        }

        /// <summary>
        /// 获取实时数据
        /// </summary>
        public void StartReal()
        {
			//暂时不启用PDB
             oilBallastService = new RealOilBallastServiceImpl(SysConfig.PDBConnStr, viewModel);
        }

        public bool IsInit()
        {
            return oilBallastService != null;
        }

        /// <summary>
        /// 开始模拟
        /// </summary>
        public void StartImitate()
        {
            //将viewModel初始化
            oilBallastService = new ImitateOilBallastServiceImpl(viewModel, new DBTankTaskService());
        }

        public void SetImitateTime(DateTime currentTime)
        {
            if (oilBallastService != null)
            {
                oilBallastService.ReflushData(currentTime);
            }
        }

        /// <summary>
        /// 是否显示舱室的状态
        /// </summary>
        public static readonly DependencyProperty ShowTankStateProperty = DependencyProperty.Register(
            "ShowTankState", typeof(bool), typeof(UCOilBallast), new PropertyMetadata(true));
        public bool ShowTankState
        {
            set { SetValue(ShowTankStateProperty, value); }
            get { return (bool)GetValue(ShowTankStateProperty); }
        }

        private void NTank_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            // 鉴权操作
            if (!AuthUtil.IsHasPermission())
            {
                return;
            }
            NTank tank = (NTank)sender;
			OnAddTankTask?.Invoke(tank.TankTitle);
			//OnAddTankTask?.Invoke(Convert.ToString(tank.Tag));^
		}

		private void NBwtTank_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			// 鉴权操作
			if (!AuthUtil.IsHasPermission())
			{
				return;
			}
			NTankMin tank = (NTankMin)sender;
			OnAddBwtTankTask?.Invoke(tank.TankTitle);
			//OnAddTankTask?.Invoke(Convert.ToString(tank.Tag));^
		}

		//这里针对阀门报验项目临时这么处理，双击即改变当前阀门启停状态
		//private OpcUaClient uaClient;
		private void UCValve_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			try
			{
				if (TankConstant.tagList_valveStatus == null)
					return;
				UCValve valve = (UCValve)sender;

				//这里后面要统一
				string old_valvename = valve.Name;
				string valvename = old_valvename.Replace("_", "-");
				//tags保存所有与valvename相关的通讯点信号
				List<OPCTag> tags = new List<OPCTag>();
				foreach (OPCTag tag in TankConstant.tagList_valveStatus)
				{
					if (tag.DispName.Contains(valvename))
					{
						tags.Add(tag);
					}
				}
				if(tags.Count > 0)
				{
					UCValveDialog ucv = new UCValveDialog(valvename, tags);
					ucv.ShowDialog();
					return;
				}
				return;

                foreach (OPCTag tag in TankConstant.tagList_valveStatus)
				{
					if (tag.DispName.Contains(valvename))
					{
						string opcname = tag.OpcName;
						//修改阀门的控制点位及部分逻辑，控制点位为SCM_Open和SCM_Close
						if (opcname.Contains("StatusOpened") || opcname.Contains("StatusClosed"))
						{
							string status_tag = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
							DataValue status_data = App.UaClient.ReadNode(status_tag);

							bool status = Convert.ToBoolean(status_data.Value);
							if (status == true)
							{
								string cmd_tag1 = null; //设置为0的控制点位
								string cmd_tag2 = null; //设置为1的控制点位
								if (opcname.Contains("StatusOpened"))
								{
									if (TankConstant.g_Debug)
									{
										cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
										string opcname2 = opcname.Replace("StatusOpened", "StatusClosed");
										cmd_tag2 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname2);
									}
									else 
									{
										string newopcname = opcname.Replace("StatusOpened", "SCM_Close");
										cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, newopcname);
									}
								}
								else if (opcname.Contains("StatusClosed"))
								{
									if (TankConstant.g_Debug)
									{
										cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
										string opcname2 = opcname.Replace("StatusClosed", "StatusOpened");
										cmd_tag2 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname2);
									}
									else
									{
										string newopcname = opcname.Replace("StatusClosed", "SCM_Open");
										cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, newopcname);
									}
								}
								if (cmd_tag1.Length > 0/* && cmd_tag2.Length > 0*/)
								{
									var dialgoResult = MessageBox.Show("确认修改信号下发?", "提示", MessageBoxButton.YesNo);
									if (dialgoResult == MessageBoxResult.Yes)
									{
										//DEBUG 下发数据类型
										if (TankConstant.g_Debug)
										{
											App.UaClient.WriteNode<Int32>(cmd_tag1, 0);
											App.UaClient.WriteNode<Int32>(cmd_tag2, 1);
										}
										else
										App.UaClient.WriteNode<Int32>(cmd_tag1, 1);
									}
								}
								return;
							}
						}
						//if (opcname.Contains("StatusOpened") || opcname.Contains("StatusClosed"))
						//{
						//	string status_tag = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
						//	DataValue status_data = App.UaClient.ReadNode(status_tag);

						//	bool status = Convert.ToBoolean(status_data.Value);
						//	if (status == true)
						//	{
						//		string cmd_tag1 = null; //设置为0的控制点位
						//		string cmd_tag2 = null; //设置为1的控制点位
						//		if (opcname.Contains("StatusOpened"))
						//		{
						//			//string newopcname = opcname.Replace("StatusOpened", "SCM_Close");
						//			cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
						//			string opcname2 = opcname.Replace("StatusOpened", "StatusClosed");
						//			cmd_tag2 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname2);
						//		}
						//		else if(opcname.Contains("StatusClosed"))
						//		{
						//			//string newopcname = opcname.Replace("StatusClosed", "SCM_Open");
						//			cmd_tag1 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname);
						//			string opcname2 = opcname.Replace("StatusClosed", "StatusOpened");
						//			cmd_tag2 = string.Format("{0}{1}", SysConfig.OPC_ADD_PRE, opcname2);
						//		}
						//		if (cmd_tag1.Length > 0 && cmd_tag2.Length > 0)
						//		{
						//			var dialgoResult = MessageBox.Show("确认修改信号下发?", "提示", MessageBoxButton.YesNo);
						//			if (dialgoResult == MessageBoxResult.Yes)
						//			{
						//				App.UaClient.WriteNode<Int32>(cmd_tag1, 0);
						//				App.UaClient.WriteNode<Int32>(cmd_tag2, 1);
						//			}
						//		}
						//		return;
						//	}
						//}
					}
				}
			}
			catch (Exception ex)
			{
				CommUtil.AddSystemLog(0, 1, ex.Message);
			}
		}

		private void UCAdjValve_MouseClick(object sender, MouseButtonEventArgs e)
		{
			try
			{
				if (TankConstant.tagList_valveStatus == null)
					return;
				UCValve valve = (UCValve)sender;

				//这里后面要统一
				string old_valvename = valve.Name;
				string valvename = old_valvename.Replace("_", "-");
				//tags保存所有与valvename相关的通讯点信号
				List<OPCTag> tags = new List<OPCTag>();
				foreach (OPCTag tag in TankConstant.tagList_valveStatus)
				{
					if (tag.DispName.Contains(valvename))
					{
						tags.Add(tag);
					}
				}
				if (tags.Count > 0)
				{
					UCAdjValveDialog ucv = new UCAdjValveDialog(valvename, tags);
					ucv.ShowDialog();
					return;
				}
				return;
			}
			catch (Exception ex)
			{
				CommUtil.AddSystemLog(0, 1, ex.Message);
			}
		}

		private void UCPump_MouseUp(object sender, MouseButtonEventArgs e)
		{
			NPump pump = (NPump)sender;
			string oldpumpname = pump.Name;
			string pumpname = oldpumpname.Replace("_", " ");
			try
			{
				if (TankConstant.tagList_pumpStatus == null)
					return;

				//tags保存所有与valvename相关的通讯点信号
				List<OPCTag> tags = new List<OPCTag>();
				foreach (OPCTag tag in TankConstant.tagList_pumpStatus)
				{
					if (tag.DispName.Contains(pumpname) && tag.OpcValue != null)
					{
						tags.Add(tag);
						break;
					}
				}
				if (tags.Count > 0)
				{
					UCPumpDialog ucv = new UCPumpDialog(pumpname, tags);
					ucv.ShowDialog();
					return;
				}
				return;
			}
			catch (Exception ex)
			{
				CommUtil.AddSystemLog(0, 1, ex.Message);
			}
			return;
		}
		public void SetTankStatus(ManualCalcResult calcResult)
        {
			if(oilBallastService != null)
			{
				oilBallastService.ReflushData(calcResult);
			}
		}
	}
}
